package com.yxjx.duoxue.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.htmlparser.tags.Span;

import com.baidu.location.LocationClient;
import com.tencent.stat.StatService;
import com.yxjx.duoxue.GuidingScoreDialog;
import com.yxjx.duoxue.JumpActivity;
import com.yxjx.duoxue.R;
import com.yxjx.duoxue.Yx;
import com.yxjx.duoxue.activities.ActivityIntroductionActivity;
import com.yxjx.duoxue.customview.VerticalImageSpan;
import com.yxjx.duoxue.dao.Dao;
import com.yxjx.duoxue.database.YxDataBase;
import com.yxjx.duoxue.datamodel.DMActivity;
import com.yxjx.duoxue.datamodel.DMAuth;
import com.yxjx.duoxue.datamodel.DMBaiduLocation;
import com.yxjx.duoxue.datamodel.DMCallRecord;
import com.yxjx.duoxue.datamodel.DMLocationPoint;
import com.yxjx.duoxue.datamodel.DMLocationPoints;
import com.yxjx.duoxue.datamodel.DMProduct;
import com.yxjx.duoxue.datamodel.course.DMCourse;
import com.yxjx.duoxue.datamodel.school.DMSchool;
import com.yxjx.duoxue.global.Globals;
import com.yxjx.duoxue.lbs.LocationIndicatorActivity;
import com.yxjx.duoxue.mta.stat.StatHelper;
import com.yxjx.duoxue.network.UserLoginResponse;
import com.yxjx.duoxue.payment.ClientUserKidsDTS;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.IntentSender.SendIntentException;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.sax.StartElementListener;
import android.telephony.TelephonyManager;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.StrikethroughSpan;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class Utils {
	
	private static Object sAccessSharedPreferencesLock = new Object();
	
	private static int MAX = 100000;
	
	private static int getRandom() {
		return (int) (Math.random() * MAX);
	}
	
	/**
	 * Try to get total number of Objects from "from"
	 * @param from
	 * @param total
	 * @return
	 */
	public static ArrayList<? extends Object> getRandom(ArrayList<? extends Object> from, int total) {
		HashMap<Integer, Object> ret = new HashMap<Integer, Object>();
		int start = 0;
		for (int i = 0; start < from.size() && start < total; i = (i+1) % from.size()) {
			int rax = getRandom() % from.size();
			if (rax < total && ret.get(i) == null) {
				ret.put(i, from.get(i));
				start++;
			}
			if (start == total) {
				break;
			}
		}
		
		ArrayList<Object> retArray = new ArrayList<Object>();
		for (int key : ret.keySet()) {
			if (ret.get(key) != null) {
				retArray.add(ret.get(key));
			}
		}
		return retArray;
	}
	
	/**
	 * Leads user to rating the app in market.
	 * @param context
	 */
	public static void leadUserToRatingInMarket(Context context) {
		
		Uri uri = Uri.parse("market://details?id=" + context.getPackageName());
		Intent intent = new Intent(Intent.ACTION_VIEW, uri);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		try{
			context.startActivity(intent);
		} catch (ActivityNotFoundException e) {
			Toast.makeText(context, "Couldn't launch the market !",
					Toast.LENGTH_SHORT).show();
		}
	}
	
	public static void leadUserToAppMarket(Context context, String appPkg) {
		Uri uri = Uri.parse("market://details?id=" + appPkg);
		Intent intent = new Intent(Intent.ACTION_VIEW, uri);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		try{
			context.startActivity(intent);
		} catch (ActivityNotFoundException e) {
			Toast.makeText(context, "Couldn't launch the market !",
					Toast.LENGTH_SHORT).show();
		}
	}
	
	public static boolean isAppInstalled(Context context, String pkg) {
		PackageManager pm = context.getPackageManager();
		boolean installed = false;
		try {
			pm.getPackageInfo(pkg, PackageManager.GET_ACTIVITIES);
			installed = true;
		} catch (PackageManager.NameNotFoundException e) {
			installed = false;
		}
		return installed;
	}
	
	public final static String NW_TYPE_WIFI = "WIFI";
	public final static String NW_TYPE_MOBILE = "MOBILE";
	public final static String NW_TYPE_NO_CONN = "NO_CONN";
	
	/**
	 * Get current APP version name info, such as 1.0.0
	 * @param context App's Context
	 * @return APP's versionName, used for APP updating and APP feedback.
	 */
	public static String getAppVersionName(Context context) {
		PackageManager manager;
		PackageInfo info = null;

		manager = context.getPackageManager();
		try {
			info = manager.getPackageInfo(context.getPackageName(), 0);
		} catch (NameNotFoundException e) {
			Log.e(Yx.TAG, "Name Not Found Exception");
			return null;
		}
		return info.versionName;
	}
	
	/**
	 * @param context
	 * @return the app distribute channel.
	 */
	public static String getChannelCode(Context context) {
		ApplicationInfo info;
		try {
			info = context.getPackageManager().getApplicationInfo(
					context.getPackageName(), PackageManager.GET_META_DATA);
			String channelCode = info.metaData.getString("InstallChannelCode");
			return channelCode;
		} catch (NameNotFoundException e) {
			// it should not happen.
			return "err";
		}
	}

	/**
	 * @return current time stamp in String format [yyyy-MM-dd HH:mm:ss]
	 */
	public static String getTimeStamp() {
		return getCurrentTimeStamp();
	}
	
	public static String getCurrentTimeStamp() {
		long time = System.currentTimeMillis();
		SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
		Date d1 = new Date(time);  
		String t1=format.format(d1);  
		return t1;
	}
	
	public static String getTimeStamp(long time) {
		SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日");  
		Date d1 = new Date(time);  
		String t1=format.format(d1);  
		return t1;
	}
	
	public static String getTimeStampDetail(long time) {
		SimpleDateFormat format=new SimpleDateFormat("MM-dd HH:mm");  
		Date d1 = new Date(time);  
		String t1=format.format(d1);  
		return t1;
	}
	
	/**
	 * 生成指定格式的时间戳
	 * @param time
	 * @param formatStr
	 * @return
	 */
	public static String getTimeStamp(long time, String formatStr) {
		SimpleDateFormat format=new SimpleDateFormat(formatStr);  
		Date d1 = new Date(time);  
		String t1=format.format(d1);  
		return t1;
	}
	
	public static String getTimeDuration(long start, long end) {
		return getTimeStamp(start) + "~" + getTimeStamp(end);
	}
	/**
	 * @return current DateTime Object.
	 */
	public static Date getDateTime() {
		long time = System.currentTimeMillis();
		Date d1 = new Date(time);
		return d1;
	}
	
	/**
	 * try to get phone num
	 * @param context
	 * @return
	 */
	public static String getPhoneNum(Context context) {
		
		// 首先尝试返回注册号码
		UserLoginResponse ulRsp = UserLoginResponse.getInstance(context);
		if (ulRsp != null) {
			return ulRsp.getPhoneNumber();
		}
		// 其次尝试返回SIM卡中存放的手机号
		TelephonyManager tm = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		// try to get native phone number.
		String num = tm.getLine1Number();
		if (num == null) {
			num = "none";
		}
		return num;
	}
	
	/**
	 * Get user's phone number.
	 * @param context
	 * @return
	 */
	public static String getFullDeviceId(Context context) {
		// get software version and app version.
		String ret = Utils.getSoftwareInfo() + 
				"[appversion]#" + Utils.getAppVersionName(context);
		
		//  try to get channel
		ret += "[channel]#" + getChannelCode(context);
		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		
		// try to get native phone number.
		String tag = "[phone]#";
		String num = tm.getLine1Number();
		ret += (tag + num);
		
		// try to get IMSI.
		num = tm.getSubscriberId();
		tag = "[imsi]#";
		ret += (tag + num);
		
		// try to get IMEI.
		num = tm.getDeviceId();
		tag = "[imei]#";
		ret += (tag + num);
		
		// try to get location des;
		num = getLocationDes(context);
		tag = "[loc]#";
		ret += (tag + num);
		
		// try to get Location gps des;
		num = getGpsDes(context);
		tag = "[gps]#";
		ret += (tag + num);
		
		return ret;
	}
	
	/**
	 * 获取位置信息描述
	 * @param context
	 * @return
	 */
	private static String getLocationDes(Context context) {
		DMBaiduLocation location = DMBaiduLocation.getLocation(context);
		return location == null ? "" : location.getAddrStr();
	}
	
	/**
	 * 获取gps信息
	 * @param context
	 * @return
	 */
	private static String getGpsDes(Context context) {
		DMBaiduLocation location = DMBaiduLocation.getLocation(context);
		return location == null ? "" : "" + location.getLatitude() + "," + location.getLongtitude();
	}
	
	public static String getShortDeviceId(Context context) {
		return getFullDeviceId(context);
	}
	
	/** 
	 * XG push使用的ID
	 * @param context
	 * @return
	 */
	public static String getXgPushId(Context context) {
		
//		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//		// try to get IMSI.
//		String num = tm.getSubscriberId();
//		String tag = "[imsi]#";
//		ret += (tag + num);
//		// try to get IMEI.
//		num = tm.getDeviceId();
//		tag = "[imei]#";
//		ret += (tag + num);
		
		String ret = "";
		UserLoginResponse ulRsp = UserLoginResponse.getInstance(context);
		if (ulRsp != null) {
			ret = ulRsp.getPhoneNumber();
		}
		return ret;
	}
	
	/**
	 * Get device's ScreenSize, CPU name, RAM size.
	 * @param context
	 * @return
	 */
	public static String getHardwareInfo(Context context) {
		String ret = "";
    	DisplayMetrics dm = new DisplayMetrics();
		if (context instanceof Activity) {
			((Activity) context).getWindowManager().getDefaultDisplay()
					.getMetrics(dm);
			ret += "ScreenSize# " + dm.widthPixels + " X " + dm.heightPixels
					+ " ";
		}
    	ret += "CpuName# " + getCpuName() + " ";
    	ret += "RAM# " + getMemTotal() + "K";
    	
		return ret;
	}
	
	/**
	 * Get device OS name, SDK version and etc.
	 * @return
	 */
	public static String getSoftwareInfo() {
		String phoneInfo = "[DN]#" + android.os.Build.PRODUCT;
        phoneInfo += "[V]#" + android.os.Build.VERSION.RELEASE;
		return phoneInfo;
	}
	
	/**
	 * 返回用于记录用户行为的版本信息
	 * @param context
	 * @return
	 */
	public static String getAllVersionInfo(Context context) {
		return Utils.getSoftwareInfo() + "[appversion]#" + Utils.getAppVersionName(context);
	}
	
	
	/**
	 * Get current network status.
	 * @param context
	 * @return WIFI CONNECTED, MOBILE DATA CONNECTED or NO DATA CONNECTION.
	 */
	public static String getNetworkInfo(Context context) {
		ConnectivityManager connectionManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = connectionManager.getActiveNetworkInfo();
		
		if (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI) {
			return NW_TYPE_WIFI;
		} else if (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE) {
			return NW_TYPE_MOBILE;
		} else {
			return NW_TYPE_NO_CONN;
		}
	}
	
	private static String getCpuName() {
		try {
			FileReader fr = new FileReader("/proc/cpuinfo");
			BufferedReader br = new BufferedReader(fr);
			String text = br.readLine();
			String[] array = text.split(":\\s+", 2);
			for (int i = 0; i < array.length; i++) {
			}
			return array[1];
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static long getMemTotal() {
		long mTotal;
		// /proc/meminfo parse
		String path = "/proc/meminfo";
		String content = null;
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(path), 8);
			String line;
			if ((line = br.readLine()) != null) {
				content = line;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		// beginIndex
		int begin = content.indexOf(':');
		// endIndex
		int end = content.indexOf('k');

		content = content.substring(begin + 1, end).trim();
		mTotal = Integer.parseInt(content);
		return mTotal;
	}
	
    /**
     * get Display's width and height.
     * @param activity
     * @return
     */
	public static int[] getDisplayWidthHeight(Activity activity) {
		
		int[] ret = new int[2];
		DisplayMetrics dm = new DisplayMetrics();
		activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
		ret[0] = dm.widthPixels;
		ret[1] = dm.heightPixels;
		
		return ret;
	}
	
	/**
	 * Is str match Mobile Number format
	 * @param str
	 * @return
	 */
	public static boolean isMobileNumber(String str) {
		if (str == null) {
			return false;
		}
		return str.matches("1[3|4|5|7|8][0-9]{9}");
	}
	
	/**
	 * 6到32位密码
	 * @param str
	 * @return
	 */
	public static boolean isPasswordFormat(String str) {
		if (str == null) {
			return false;
		}
		return str.matches("^.{6,32}$");
	}
	
	/**
	 * Remove the empty item in ArrayList.
	 * @param items
	 * @return
	 */
	public static <E> ArrayList<E> trimArray(ArrayList<E> items) {
		ArrayList<E> ret = new ArrayList<E>();
		if (items != null) {
			for (E item : items) {
				if (item != null) {
					ret.add(item);
				}
			}
		}
		return ret;
	}
	
	///////get content text of pages.
	/**
	 * Get course category and required age duration.
	 * @param course
	 * @return
	 */
	public static String getCategoryText(final DMCourse course) {
		return course.getCourseType2() + " | " + course.getAgeDesc();
	}
	
	/**
	 * Get course's price description text.
	 * @param course
	 * @return
	 */
	public static String getPriceText(DMCourse course) {
		if (course.getShowPerPrice() == 1) {
			if (course.getPerPrice() > 0) {
				return "" + course.getPerPrice() + "元／次";
			} else {
				return "免费";
			}
		} else if (course.getShowPackagePrice() == 1) {
			if (course.getPackagePrice() > 0) {
				return "" + course.getPackagePrice() + "元／套";
			} else {
				return "免费";
			}
		} else {
			return "价格面议";
		}
	}
	
	
	/**
	 * Dial A Number from list with a dialog
	 * @param context
	 * @param item 课程/xu
	 */
	public static void dialPhoneNumber(final Context context, final Object item) {
		
		final String phoneNumber;
		if (item instanceof DMActivity) {
			phoneNumber = ((DMActivity) item).getContactPhone();
			StatHelper.addKVEvent(context, "event_activity_call", 
					StatHelper.KEY_ACTIVITY, ((DMActivity) item).getActivityId());
			
		} else if (item instanceof DMSchool) {
			phoneNumber = ((DMSchool) item).getPhoneNumbers();
			
			///MTA stat start
			Properties prop = StatHelper.getBasicProp(context);
			prop.put(StatHelper.KEY_SCHOOL, ((DMSchool) item).getId());
			StatService.trackCustomKVEvent(context, "event_school_call_click", prop);
			///MTA stat end
			
		} else if (item instanceof DMCourse) {
			phoneNumber = ((DMCourse) item).getSchoolPhone();
			
			///MTA stat start
			Properties prop = StatHelper.getBasicProp(context);
			prop.put(StatHelper.KEY_COURSE, ((DMCourse) item).getCourseId());
			prop.put(StatHelper.KEY_SCHOOL, ((DMCourse) item).getSchool().getId());
			StatService.trackCustomKVEvent(context, "event_course_call_click", prop);
			///MTA stat end
			
		} else {
			return;
		}
		
		if (UIHelper.isEmpty(phoneNumber)) {
			Toast.makeText(context, "电话号码不存在" +  phoneNumber, Toast.LENGTH_SHORT).show();
			return;
		}
		
		//////////////
		LinearLayout linearLayoutMain = new LinearLayout(context);//自定义一个布局文件
		linearLayoutMain.setLayoutParams(new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
		ListView listView = new ListView(context);//this为获取当前的上下文
		listView.setLayoutParams(new LayoutParams(android.widget.AbsListView.LayoutParams.MATCH_PARENT, 
				android.widget.AbsListView.LayoutParams.WRAP_CONTENT));
		listView.setFadingEdgeLength(0);
		
		String[] numbers = phoneNumber.split(",");
		List<Map<String, String>> nameList = new ArrayList<Map<String, String>>();//建立一个数组存储listview上显示的数据
		for (int m = 0; m < numbers.length; m++) {//initData为一个list类型的数据源
			Map<String, String> nameMap = new HashMap<String, String>();
			nameMap.put("name", numbers[m]);
			nameList.add(nameMap);
		}

		SimpleAdapter adapter = new SimpleAdapter(context,
				nameList, R.layout.item_call_list,
				new String[] { "name" },
				new int[] { R.id.tele_number });
		listView.setAdapter(adapter);

		linearLayoutMain.addView(listView);//往这个布局中加入listview

		final AlertDialog dialog = new AlertDialog.Builder(context)
//				.setTitle("确认拨打号码")
				.setView(linearLayoutMain)//在这里把写好的这个listview的布局加载dialog中
				.setMessage("告知学校是从《多学》获知课程信息，即有机会享受免费试听")
				.setNegativeButton("取消", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				}).
				create();
		dialog.setCanceledOnTouchOutside(false);//使除了dialog以外的地方不能被点击
		dialog.show();
		listView.setOnItemClickListener(new OnItemClickListener() {//响应listview中的item的点击事件

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				TextView text = (TextView) arg1.findViewById(R.id.tele_number);
				Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+ text.getText()));  
		        context.startActivity(intent);
				dialog.cancel();
				
				///////MTA stat
				if (item instanceof DMActivity) {
					
					
				} else if (item instanceof DMSchool) {
					
					Properties prop = StatHelper.getBasicProp(context);
					prop.put(StatHelper.KEY_SCHOOL, ((DMSchool) item).getId());
					StatService.trackCustomKVEvent(context, "event_school_call_ok", prop);
					
				} else if (item instanceof DMCourse) {
					
					Properties prop = StatHelper.getBasicProp(context);
					prop.put(StatHelper.KEY_COURSE, ((DMCourse) item).getCourseId());
					prop.put(StatHelper.KEY_SCHOOL, ((DMCourse) item).getSchool().getId());
					StatService.trackCustomKVEvent(context, "event_course_call_ok", prop);
					
				}
				///////MTA stat
				// 将记录写到数据库。
				DMCallRecord callRecord = DMCallRecord.from(item, context);
				YxDataBase.getInstance(context).insertCallRecord(callRecord);
			}
		});
		/////////////
	}
	
	/**
	 * write value to sharedPreference
	 * @param ctx
	 * @param key
	 * @param value
	 */
	public static void writeToSharePreference(Context ctx, String key, String value) {
		synchronized (sAccessSharedPreferencesLock) {
			SharedPreferences sp = ctx.getSharedPreferences(Yx.KEY_SF, Context.MODE_PRIVATE);
			SharedPreferences.Editor editor = sp.edit();
			editor.putString(key, value);
			editor.commit();
		}
	}
	
	public static String getValueFromSharedPreference(Context ctx, String key) {
		synchronized (sAccessSharedPreferencesLock) {
			SharedPreferences sp = ctx.getSharedPreferences(Yx.KEY_SF, Context.MODE_PRIVATE);
			return sp.getString(key, "");
		}
	}
	
	public static void registerPreferenceChangeListener(Context ctx, SharedPreferences.OnSharedPreferenceChangeListener listener) {
		synchronized (sAccessSharedPreferencesLock) {
			SharedPreferences sp = ctx.getSharedPreferences(Yx.KEY_SF, Context.MODE_PRIVATE);
			sp.registerOnSharedPreferenceChangeListener(listener);
		}
	}
	
	public static boolean isLogin(Context context) {
		return !UIHelper.isEmpty(Utils.getValueFromSharedPreference(context, Yx.KEY_SESSION_KEY));
	}
	
	public static boolean isReadyForLogin(Context context) {
		return !UIHelper.isEmpty(Utils.getValueFromSharedPreference(context, Yx.KEY_PHONE_NUM))
				&& !UIHelper.isEmpty(Utils.getValueFromSharedPreference(context, Yx.KEY_PHONE_PASSWORD));
	}
	
	public static void logd(String text) {
		Log.d("CMM4", text);
	}
	
	public static void showLocationInMap(Context context, String gps, String tag, String pageTitle) {
		Intent intent = new Intent(context, LocationIndicatorActivity.class);
		if (UIHelper.isEmpty(gps)) {
			Utils.logd("parse GPS error，gps = " + gps);
			return;
		}
		String[] posStr = gps.split(",");
		double[] posDouble = new double[2];
		
		try {
			posDouble[0] = Double.valueOf(posStr[0]);
			posDouble[1] = Double.valueOf(posStr[1]);
		} catch (Exception e) {
			Utils.logd("parse GPS error，gps = " + gps);
			return;
		}
		
		intent.putExtra(Yx.KEY_GPS_LAT, posDouble[1]);
		intent.putExtra(Yx.KEY_GPS_LOG, posDouble[0]);
		intent.putExtra(Yx.KEY_GPS_TITLE, tag);
		intent.putExtra(Yx.KEY_PAGE_TITLE, pageTitle);
		context.startActivity(intent);
	}
	
	private static void showLocationsInMapInternal(Context context, DMLocationPoints points, String pageTitle) {
		if (points == null || points.getList() == null || points.getList().size() <= 1) {
			return;
		}
		Intent intent = new Intent(context, LocationIndicatorActivity.class);
		intent.putExtra(Yx.KEY_MULTI_LOCATIONS, points);
		intent.putExtra(Yx.KEY_PAGE_TITLE, pageTitle);
		context.startActivity(intent);
	}
	
	public static void showLocationsInMap(Context context, DMLocationPoints points, String pageTitle) {
		if (points == null || points.getList() == null || points.getList().size() == 0) {
			return;
		} else if (points.getList().size() == 1) {
			String gps = points.getList().get(0).getGps();
			String tag = points.getList().get(0).getAddress();
			showLocationInMap(context, gps, tag, pageTitle);
		} else {
			showLocationsInMapInternal(context, points, pageTitle);
		}
	}
	
	/**
	 * String to float
	 * @param str
	 * @return
	 */
	public static float floatFrom(String str) {
		if (UIHelper.isEmpty(str)) {
			return 0.0f;
		} else {
			return Float.valueOf(str);
		}
	}
	
	/**
	 * 将手机号的中间6位加上mask
	 * @param cellNum
	 * @return
	 */
	public static String maskCell(String cellNum) {
		if (UIHelper.isEmpty(cellNum)) {
			return null;
		}
		if (cellNum.length() < 11) {
			StringBuilder sb = new StringBuilder();
			sb.append(cellNum.substring(0, 3));
			sb.append("******");
			return sb.toString();
		} else {
			
			StringBuilder sb = new StringBuilder();
			sb.append(cellNum.substring(0, 3));
			sb.append("******");
			sb.append(cellNum.substring(9, 11));
			return sb.toString();
		}
	} 
	
	private static double EARTH_RADIUS = 6378.137;// 地球半径

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}

	/**
	 * 	// 计算两个地点之间的距离
	 * @param lat1
	 * @param lng1
	 * @param lat2
	 * @param lng2
	 * @return
	 */
	public static double GetDistance(double lat1, double lng1, double lat2,
			double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);

		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
				+ Math.cos(radLat1) * Math.cos(radLat2)
				* Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
//		s = Math.round(s * 10000) / 10000;
		return s;
	}
	
	public static double[] getLogLat(String str) {
		if (UIHelper.isEmpty(str)) {
			return null;
		}
		String[] posStr = str.split(",");
		double[] posDouble = new double[2];
		
		try {
			posDouble[0] = Double.valueOf(posStr[0]);
			posDouble[1] = Double.valueOf(posStr[1]);
		} catch (Exception e) {
			return null;
		}
		return posDouble;
	}
	/**
	 * 获取schoolGps地点与当前位置的距离
	 * @param ctx
	 * @param schoolGps
	 * @return
	 */
	public static String getDistanceDesc(Context ctx, String schoolGps) {
		DMBaiduLocation location = DMBaiduLocation.getLocation(ctx);
		Utils.logd("getDistanceDesc " + schoolGps + ", location = " + location); 
		
		if (UIHelper.isEmpty(schoolGps)) {
			return "未知距离";
		}
		String[] posStr = schoolGps.split(",");
		double[] posDouble = new double[2];
		
		try {
			posDouble[0] = Double.valueOf(posStr[0]);
			posDouble[1] = Double.valueOf(posStr[1]);
		} catch (Exception e) {
			Utils.logd("parse GPS error，gps = " + schoolGps);
			return "未知距离";
		}
		
		if (location != null) {
			double dis = GetDistance(location.getLatitude(), location.getLongtitude(), posDouble[1], posDouble[0]);
//			return "" + dis + "km";

			if (dis < 1) {
				return "" + (int) (dis * 1000.0) + "m";
			} else {
				return "" + String.format("%.1f", dis) + "km";
			}
		}
		return "距离未知";
	}
	
	// 用于记录用户的行为。
	
	public static String[] getReminderDate() {
		String[] ret = new String[3];
		
		long time = System.currentTimeMillis();
		time += 7 * 24 * 3600 * 1000;
		// 7天后的18:00 提醒用户
		SimpleDateFormat format=new SimpleDateFormat("yyyyMMdd");  
		Date d1 = new Date(time);  
		String t1=format.format(d1);  
		ret[0] = t1;
		ret[1] = "18";
		ret[2] = "00";
		
		return ret;
	}
	
	/**
	 * 询问用户是否要去做打分:
	 * 当用户点评或购买或预约或打开app5次时在回到首页时弹出；
	 * a. 用户点击“五星”，弹出应用市场，以后永不再现。
	 * b. 用户点击“残忍拒绝”，本版本不再出现
	 * c. 用户点击“吐槽"
	 * @param context
	 */
	public static void askUserToScore(Context context) {
		String feedback = Utils.getValueFromSharedPreference(context, Yx.KEY_COMMENT_BAD);

		// 已经点评或吐槽过
		if ("1".equals(Utils.getValueFromSharedPreference(context, Yx.KEY_GIVE_FIVE_STAR))
				|| "1".equals(Utils.getValueFromSharedPreference(context, Yx.KEY_COMMENT_BAD))) {
			// do nothing
			return;
		// 已经点过拒绝这一版本
		} else if ("1".equals(Utils.getValueFromSharedPreference(context, Yx.KEY_REJECT))) {
			if (Utils.getAppVersionName(context).equals(Utils.getValueFromSharedPreference(context, Yx.KEY_LAST_REJECT_VERSION))) {
				// do nothing
				return;
			} else {
				askUserToScoreInternal(context);
			}
		} else {
			// 去引导页。
			if ("1".equals(Utils.getValueFromSharedPreference(context,
					Yx.KEY_HAS_APPOINT_OR_BUY_OR_COMMENT))) {
				askUserToScoreInternal(context);
			}
		}
	}
	
	private static void askUserToScoreInternal(Context context) {
		if (Globals.getInstance(context).isShowingDialog()) {
			return;
		}
		
		Dialog dialog = new GuidingScoreDialog(context, R.style.MyDialog);
		dialog.show();
		Globals.getInstance(context).setShowingDialog(true);
	}
	
	private static long getTwoDaysAgo() {
		return System.currentTimeMillis() - (2l * 24l * 3600l * 1000l);
	}
	
	public static String getRemindTime(long dueTime) {
		long current = System.currentTimeMillis();
		if (dueTime <= current) {
			return "已过期";
		}
		long delta = dueTime - current;
		long hour = 3600l * 1000l;
		long day = 24l * hour;
		if (delta > day) {
			return "剩" + delta/day + "天";
		} else {
			return "剩" + delta/hour + "小时";
		}
	}
	
	public static String getCount(int count) {
		if (count < 10000) {
			return "" + count;
		} else {
			float countFloat =  (float) count / 10000.0f;
			return "" + String.format("%.1f", countFloat) + "万";
		}
	}
	
	/**
	 * 混色显示 xx浏览
	 * @return
	 */
	public static SpannableStringBuilder getStyleString(int count) {
		if (count == 0) {
			return new SpannableStringBuilder();
		}
		String text = getCount(count);
		String tail = "人感兴趣";
		SpannableStringBuilder style = new SpannableStringBuilder(text + tail);
		style.setSpan(new ForegroundColorSpan(0xfffa952f), 0, text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
		return style;
	}
	
	/**
	 * 认证区域添加某个label
	 * {\"id\":1,\"authName\":\"公司认证\",\"authDes\":null},
	 * {\"id\":2,\"authName\":\"个人认证\",\"authDes\":null},
	 * {\"id\":3,\"authName\":\"免费试听\",\"authDes\":null},
	 * {\"id\":4,\"authName\":\"7天退款\",\"authDes\":null},
	 * {\"id\":5,\"authName\":\"15天退款\",\"authDes\":null},
	 * {\"id\":6,\"authName\":\"30天退款\",\"authDes\":null},
	 * {\"id\":7,\"authName\":\"折扣\"
	 * {\"id\":8,\"authName\":\"1元课\"
	 * TODO: add labels of 1 元课。
	 * @param container
	 * @param auths
	 */
	public static void addLabels(ViewGroup container, ArrayList<DMAuth> auths) {
		//
		int[] labelIds = {1, 4, 7, 8};
		HashMap<Integer, Integer> idResIdMap = new HashMap<Integer, Integer>() {
			{
				put(1, R.drawable.lable_cerf);
				put(4, R.drawable.lable_ensure);
				put(7, R.drawable.lable_discout);
				put(8, R.drawable.lable_yiyuan);
			}
		};
		
		container.removeAllViews();
		for (int resId : getLabelsResId(auths, idResIdMap, labelIds)) {
			View labelItem = LayoutInflater.from(container.getContext()).inflate(R.layout.item_label, null);
			labelItem.findViewById(R.id.label).setBackgroundResource(resId);
			container.addView(labelItem);
		}
	}
	
	public static void addSchoolOnlyLabels(ViewGroup container, ArrayList<DMAuth> auths) {
		//
		int[] labelIds = {1};
		HashMap<Integer, Integer> idResIdMap = new HashMap<Integer, Integer>() {
			{
				put(1, R.drawable.lable_cerf);
			}
		};
		
		container.removeAllViews();
		for (int resId : getLabelsResId(auths, idResIdMap, labelIds)) {
			View labelItem = LayoutInflater.from(container.getContext()).inflate(R.layout.item_label, null);
			labelItem.findViewById(R.id.label).setBackgroundResource(resId);
			container.addView(labelItem);
		}
	}
	
	public static void addSchoolOnlyLabels(TextView textview, String title, ArrayList<DMAuth> auths) {
		//
		int[] labelIds = {1};
		HashMap<Integer, Integer> idResIdMap = new HashMap<Integer, Integer>() {
			{
				put(1, R.drawable.class_detail_cerf);
			}
		};
		
		ArrayList<Integer> labels = getLabelsResId(auths, idResIdMap, labelIds);
		setLabeledText(textview, title, labels);
	}
	
	public static void addCourseOnlyLabels(ViewGroup container, ArrayList<DMAuth> auths) {
		//
		int[] labelIds = {4, 7};
		HashMap<Integer, Integer> idResIdMap = new HashMap<Integer, Integer>() {
			{
				put(4, R.drawable.lable_ensure);
				put(7, R.drawable.lable_discout);
			}
		};
		
		container.removeAllViews();
		for (int resId : getLabelsResId(auths, idResIdMap, labelIds)) {
			View labelItem = LayoutInflater.from(container.getContext()).inflate(R.layout.item_label, null);
			labelItem.findViewById(R.id.label).setBackgroundResource(resId);
			container.addView(labelItem);
		}
	}
	
	private static ArrayList<Integer> getLabelsResId(ArrayList<DMAuth> auths, HashMap<Integer, Integer> idResIdMap, int[] labelIds) {
		ArrayList<Integer> ret = new ArrayList<Integer>();
		
		if (auths == null) {
			return ret;
		} else {
			for (DMAuth auth : auths) {
				for (int i : labelIds) {
					if (auth.getId() == i) {
						ret.add(idResIdMap.get(i));
						break;
					}
				}
			}
		}
		return ret;
	}
	
	/**
	 * set Html text, 前面为title的字符串，后面为label图片
	 */
	private static void setLabeledText(TextView textview, String title, ArrayList<Integer> labelIcons) {
		textview.setText("");
		SpannableString spanText = new SpannableString(title);
		textview.append(spanText);
		
		int labelNum = labelIcons == null ? 0 : labelIcons.size();
		if (labelNum == 0) {
			return;
		}
		spanText = new SpannableString(String.valueOf(new char[labelNum]));
		for (int i = 0; i < labelIcons.size(); i ++) {
			int labelIcon = labelIcons.get(i);
			Drawable drawable = textview.getResources().getDrawable(labelIcon);
			int yOffset = 0;
			int xOffset = 5;
			drawable.setBounds(xOffset, yOffset, drawable.getIntrinsicWidth() + xOffset, drawable.getIntrinsicHeight() + yOffset);
			spanText.setSpan(new VerticalImageSpan(drawable), i, i + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
		}
		textview.append(spanText);
	}
	
	/**
	 * set Html text
	 * 参考 http://www.docin.com/p-448247930.html
	 * @param textView
	 * @param product
	 */
	public static void setPriceText(TextView textView, DMProduct product) {
		Context context = textView.getContext();
		int oldPrice = product.getCostPrice();
		int nowPrice = product.getDiscountPrice();
		textView.setText("");
		SpannableString spanText = new SpannableString("￥" + nowPrice + "元");
		spanText.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.yx_red_font)), 0, spanText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
		spanText.setSpan(new AbsoluteSizeSpan(context.getResources().getDimensionPixelSize(R.dimen.yx_font_2)), 0, spanText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
		textView.append(spanText);
		
		if (nowPrice != oldPrice) {
			spanText = new SpannableString("￥");
			spanText.setSpan(new ForegroundColorSpan(context.getResources()
					.getColor(R.color.yx_grey_a2)), 0, spanText.length(),
					Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
			spanText.setSpan(new AbsoluteSizeSpan(context.getResources()
					.getDimensionPixelSize(R.dimen.yx_font_1)), 0, spanText
					.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
			textView.append(spanText);

			spanText = new SpannableString("" + oldPrice + "元");
			spanText.setSpan(new StrikethroughSpan(), 0, spanText.length(),
					Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
			spanText.setSpan(new ForegroundColorSpan(context.getResources()
					.getColor(R.color.yx_grey_a2)), 0, spanText.length(),
					Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
			spanText.setSpan(new AbsoluteSizeSpan(context.getResources()
					.getDimensionPixelSize(R.dimen.yx_font_1)), 0, spanText
					.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
			textView.append(spanText);
		}
	}
	
	
	public static void writeUserLoginResponseToSharedPreference(Context context, UserLoginResponse ret) {
		Utils.writeToSharePreference(context, 
				Yx.KEY_PHONE_NUM, ret.getPhoneNumber());
		Utils.writeToSharePreference(context, 
				Yx.KEY_SESSION_KEY, ret.getSessionKey());
		Utils.writeToSharePreference(context, 
				Yx.KEY_SID, ret.getSid());
		Utils.writeToSharePreference(context, 
				Yx.KEY_UID, ret.getuId());
		Utils.writeToSharePreference(context,
				Yx.KEY_PHONE_PASSWORD, ret.getUserPassword());
		ClientUserKidsDTS userInfo = ret.getKidInfo();
		Dao.setUserKidInfo(context, userInfo);
	}
	
	public static String[] parseSchema(String schemaStr) {
		if (UIHelper.isEmpty(schemaStr)) {
			return null;
		}
		
		String postFix = schemaStr.substring(JumpActivity.PREFIX_DATA.length());
		if (UIHelper.isEmpty(postFix)) {
			return null;
		}
		
		String[] items = postFix.split("/");
		if (items == null || items.length != 2) {
			return null;
		}
		
		return items;
	}
	
	public static void tryCloseGps(Context context) {
		LocationClient client = Globals.getInstance(context).getLocationClient();
		if (client != null) {
			if (client.isStarted()) {
				client.getLocOption().setOpenGps(false);
				client.stop();
			}
		}
	}
	
	public static String getAgeDesc(ClientUserKidsDTS kidInfo) {
		// 学生的年月属性非法，则使用年龄属性
		if (kidInfo.getKidsBirthMonth() < 0 || kidInfo.getKidsBirthYear() < 0) {
			return "" + kidInfo.getKidsAge() + "岁";
		}
		int diff = getMonthCount(kidInfo);
		return (diff < 12) ? ("" + diff + "月") : ("" + diff / 12 + "岁");
	}

	public static int getMonthCount(ClientUserKidsDTS kidInfo) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(System.currentTimeMillis());
		int nowYear = cal.get(Calendar.YEAR);
		int nowMonth = cal.get(Calendar.MONTH);
		int nowMonthCount = nowYear * 12 + (nowMonth + 1);
		int kidMonthCount = kidInfo.getKidsBirthYear() * 12 + kidInfo.getKidsBirthMonth();
		int diff = nowMonthCount - kidMonthCount;
		return diff;
	}
	
	public static int getOlderYear(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(System.currentTimeMillis());
		int nowYear = cal.get(Calendar.YEAR);
		int nowMonth = cal.get(Calendar.MONTH);
		int nowMonthCount = nowYear * 12 + (nowMonth + 1);
		int kidMonthCount = year * 12 + month;
		int diff = nowMonthCount - kidMonthCount;
		return diff / 12;
	}
	
	/**
	 * @Deprecated
	 * @param context
	 * @return
	 */
	public static boolean isFirstTimeUserReg(Context context) {
		String value = Utils.getValueFromSharedPreference(context, Yx.KEY_FIRST_TIME_USER_REG);
		if (value.startsWith("false")) {
			return false;
		}
		// 标记为非第一次注册登录的状态
		Utils.writeToSharePreference(context, Yx.KEY_FIRST_TIME_USER_REG, "false");
		return true;
	}
	
	// 增加APP打开的次数
	public static void addAppOpenTime(Context context) {
		int valueInt = getOpenTimeInternal(context);
		valueInt++;
		Utils.writeToSharePreference(context, Yx.KEY_OPEN_APP_TIMES, ""
				+ valueInt);
	}

	private static int getOpenTimeInternal(Context context) {
		String value = Utils.getValueFromSharedPreference(context,
				Yx.KEY_OPEN_APP_TIMES);
		int valueInt = 0;
		try {
			valueInt = Integer.valueOf(value);
		} catch (Exception e) {
			//
		}
		return valueInt;
	}

	// 返回APP打开的次数
	public static int getAppOpenTime(Context context) {
		return getOpenTimeInternal(context);
	}

	// APP打开的次数清零
	public static void resetAppOpenTime(Context context) {
		Utils.writeToSharePreference(context, Yx.KEY_OPEN_APP_TIMES, "0");
	}
	
	/**
	 * 判断页面打开方式是否有满足key Value的参数。
	 * @param intent
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean hasKeyValue(Intent intent, String key, String value) {
		if (intent == null || intent.getExtras() == null) {
			return false;
		}
		if (UIHelper.isEmpty(key) || UIHelper.isEmpty(value)) {
			return false;
		}
		String temp = intent.getExtras().getString(key);
		return value.equals(temp);
	}
	
}
